From 4209290bc418c86dc771c66af5ffbef6ae741f41 Mon Sep 17 00:00:00 2001 From: Jehan Date: Wed, 14 Nov 2012 13:26:06 +0900 Subject: [PATCH] Bug 688217 - relies on actual DLL path for locating lib directory on Windows. --- babl/babl.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 102 insertions(+), 4 deletions(-) diff --git a/babl/babl.c b/babl/babl.c index bc3f7de..b2a03ae 100644 --- a/babl/babl.c +++ b/babl/babl.c @@ -19,18 +19,112 @@ #include "config.h" #include "babl-internal.h" +#ifdef _WIN32 +#include +#endif + static int ref_count = 0; +#ifdef _WIN32 +static HMODULE libbabl_dll = NULL; + +/* Minimal DllMain that just stores the handle to this DLL */ + +BOOL WINAPI /* Avoid silly "no previous prototype" gcc warning */ +DllMain (HINSTANCE hinstDLL, + DWORD fdwReason, + LPVOID lpvReserved); + +BOOL WINAPI +DllMain (HINSTANCE hinstDLL, + DWORD fdwReason, + LPVOID lpvReserved) +{ + switch (fdwReason) + { + case DLL_PROCESS_ATTACH: + libbabl_dll = hinstDLL; + break; + } + + return TRUE; +} + +#else #define BABL_PATH LIBDIR BABL_DIR_SEPARATOR BABL_LIBRARY +#endif /* _WIN32 */ -static const char * +/* + * Returns a list of directories if the environment variable $BABL_PATH + * is set, or the installation library directory by default. + * This directory will be based on the compilation-time prefix for UNIX + * and an actual DLL path for Windows. + * + * Returns: a string which must be freed after usage. + */ +static char * babl_dir_list (void) { - const char *ret; + char *ret; ret = getenv ("BABL_PATH"); if (!ret) - ret = BABL_PATH; + { +#ifdef _WIN32 + /* Figure it out from the location of this DLL */ + char *filename; + int filename_size; + char *sep1, *sep2; + + wchar_t w_filename[MAX_PATH]; + DWORD nSize = sizeof (w_filename) / sizeof ((w_filename)[0]); + + if (GetModuleFileNameW (libbabl_dll, w_filename, nSize) == 0) + babl_fatal ("GetModuleFilenameW failed"); + + filename_size = WideCharToMultiByte (CP_UTF8, 0, w_filename, -1, NULL, 0, + NULL, NULL); + filename = babl_malloc (sizeof (char) * filename_size); + if (!WideCharToMultiByte (CP_UTF8, 0, w_filename, -1, + filename, filename_size, NULL, NULL)) + babl_fatal ("Converting module filename to UTF-8 failed"); + + /* If the DLL file name is of the format + * \bin\*.dll, use \lib\{BABL_LIBRARY}. + * Otherwise, use the directory where the DLL is. + */ + + sep1 = strrchr (filename, BABL_DIR_SEPARATOR[0]); + *sep1 = '\0'; + + sep2 = strrchr (filename, BABL_DIR_SEPARATOR[0]); + if (sep2 != NULL) + { + if (strcasecmp (sep2 + 1, "bin") == 0) + { + char* filename_tmp; + *(++sep2) = '\0'; + filename_tmp = babl_malloc (sizeof (char) * (strlen (filename) + + strlen (BABL_DIR_SEPARATOR BABL_LIBRARY) + 4)); + strcpy (filename_tmp, filename); + babl_free (filename); + strcat (filename_tmp, "lib" BABL_DIR_SEPARATOR BABL_LIBRARY); + filename = filename_tmp; + } + } + + ret = filename; +#else + ret = babl_malloc (sizeof (char) * (strlen (BABL_PATH) + 1)); + strcpy (ret, BABL_PATH); +#endif + } + else + { + char* ret_tmp = babl_malloc (sizeof (char) * (strlen (ret) + 1)); + strcpy (ret_tmp, ret); + ret = ret_tmp; + } return ret; } @@ -41,6 +135,8 @@ babl_init (void) if (ref_count++ == 0) { + char * dir_list; + babl_internal_init (); babl_sampling_class_init (); babl_type_db (); @@ -55,7 +151,9 @@ babl_init (void) babl_extension_base (); babl_sanity (); - babl_extension_load_dir_list (babl_dir_list ()); + dir_list = babl_dir_list (); + babl_extension_load_dir_list (dir_list); + babl_free (dir_list); } } -- 2.30.2